package com.woniu.gym.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.core.exception.account.AccountException;
import com.woniu.core.exception.account.AccountExceptionCode;
import com.woniu.core.exception.gym.GymException;
import com.woniu.core.exception.gym.GymExceptionCode;
import com.woniu.core.util.PageInfo;
import com.woniu.core.util.Result;
import com.woniu.gym.client.AccountServerClient;
import com.woniu.gym.client.dto.CoachDto;
import com.woniu.gym.client.dto.CoachInfoDto;
import com.woniu.gym.dao.TApplyMapper;
import com.woniu.gym.dao.TGymBaseMapper;
import com.woniu.gym.dao.TGymCoachInfoMapper;
import com.woniu.gym.dao.TRecruitConditionMapper;
import com.woniu.gym.dto.CoachJobApplicationDto;
import com.woniu.gym.dto.GymApplicationCoachDto;
import com.woniu.gym.dto.JobDetailsDto;
import com.woniu.gym.form.SearchCoachApplicationForm;
import com.woniu.gym.form.SearchGymApplicationForm;
import com.woniu.gym.model.TApply;
import com.woniu.gym.model.TGymBase;
import com.woniu.gym.model.TGymCoachInfo;
import com.woniu.gym.model.TRecruitCondition;
import com.woniu.gym.service.TApplyService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年04月02日
 */
@Service
public class TApplyServiceImpl extends ServiceImpl<TApplyMapper, TApply> implements TApplyService {
    @Resource
    private TApplyMapper tApplyMapper;
    @Resource
    private TRecruitConditionMapper tRecruitConditionMapper;
    @Resource
    private AccountServerClient accountServerClient;
    @Resource
    private TGymCoachInfoMapper tGymCoachInfoMapper;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public PageInfo<CoachJobApplicationDto> findApplication(SearchCoachApplicationForm form) {
        Page<TApply> page = new Page<>(form.getPageNum()==null?1:form.getPageNum(),form.getPageSize()==null?5:form.getPageSize());
        QueryWrapper<TApply> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id",form.getCoachId());
        if(ObjectUtil.isAllNotEmpty(form.getApplyState())){
            wrapper.eq("apply_state",form.getApplyState());
        }
        tApplyMapper.selectPage(page,wrapper);
        List<TApply> list = page.getRecords();
        ArrayList<CoachJobApplicationDto> data = new ArrayList<>();
        for (TApply tApply : list) {
            TRecruitCondition trc = tRecruitConditionMapper.selectById(tApply.getRecruitId());
            CoachJobApplicationDto dto = BeanUtil.toBean(tApply, CoachJobApplicationDto.class);
            //将json字符串转化为对象
            JobDetailsDto jobForm = JSONUtil.toBean(trc.getJobDetails(), JobDetailsDto.class);
            dto.setJobForm(jobForm);
            dto.setJobTitle(trc.getJobTitle());
            dto.setGymNum(trc.getGymNum());
            dto.setJobSalary(trc.getJobSalary());
            dto.setCreateName(trc.getCreateName());
            dto.setCreatePhone(trc.getCreatePhone());
            data.add(dto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setList(data);
        pageInfo.setPages(page.getPages());
        return pageInfo;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public PageInfo<GymApplicationCoachDto> gymApplication(SearchGymApplicationForm form) {
        Page<TApply> page = new Page<>(form.getPageNum()==null?1:form.getPageNum(),form.getPageSize()==null?5:form.getPageSize());

        QueryWrapper<TApply> wrapper = new QueryWrapper<>();
        wrapper.eq("gym_num",form.getGymNum());
        if(ObjectUtil.isAllNotEmpty(form.getApplyState())){
            wrapper.eq("apply_state",form.getApplyState());
        }
        tApplyMapper.selectPage(page,wrapper);
        List<TApply> list = page.getRecords();
        ArrayList<GymApplicationCoachDto> data = new ArrayList<>();
        for (TApply tApply : list) {
            Result<CoachInfoDto> coachInfoDtoResult = accountServerClient.CoachInfoById(tApply.getCoachId());
            CoachInfoDto coachInfoDto = coachInfoDtoResult.getData();
            if(coachInfoDto==null || coachInfoDto.getResumeState()==0){
                throw new AccountException(AccountExceptionCode.NOT_FIND_THIS_COACH);
            }
            GymApplicationCoachDto dto = BeanUtil.toBean(tApply, GymApplicationCoachDto.class);
            dto.setResumeId(coachInfoDto.getResumeId());
            dto.setCoachRealname(coachInfoDto.getCoachRealname());
            dto.setCoachPhoto(coachInfoDto.getCoachPhoto());
            dto.setCoachIdnum(coachInfoDto.getCoachIdnum());
            dto.setCoachGender(coachInfoDto.getCoachGender());
            dto.setCoachPhone(coachInfoDto.getCoachPhone());
            dto.setCoachAge(coachInfoDto.getCoachAge());
            dto.setCoachAuthen(coachInfoDto.getCoachAuthen());
            dto.setCoachDetails(coachInfoDto.getCoachDetails());
            dto.setCoachMoney(coachInfoDto.getCoachMoney());
            dto.setWantJob(coachInfoDto.getWantJob());
            dto.setCoachGood(coachInfoDto.getCoachGood());
            data.add(dto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setList(data);
        return pageInfo;
    }

    /**
     * 教练求职申请 教练->场馆
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public CoachJobApplicationDto coachJobApplication(Integer recruitId,Integer coachId) {
        Result<CoachDto> coachDtoResult = accountServerClient.getCoachAccountById(coachId);
        CoachDto coachDto = coachDtoResult.getData();
        if(coachDto.getCoachState()==2)throw new AccountException("未实名认证，不能发送申请",400061);
        if (coachDto==null) throw new AccountException(AccountExceptionCode.USER_NOT_LOGIN);
        if (coachDto.getGymNum()!=null  || !coachDto.getGymNum().equals("")) {
            throw new AccountException("你已签约，不能发送申请",400061);
        }

        QueryWrapper<TApply> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id", coachId).eq("recruit_id", recruitId).eq("apply_state", 0);
        TApply apply = tApplyMapper.selectOne(wrapper);
        if (apply!=null) throw new AccountException("已投递该岗位，请勿重复操作",40071);

        TRecruitCondition tRecruitCondition = tRecruitConditionMapper.selectById(recruitId);
        if(tRecruitCondition==null || tRecruitCondition.getRecruitState()==0){
            throw new GymException(GymExceptionCode.RECRUIT_NOT_EXIST);
        }
        CoachInfoDto coachInfoDto = accountServerClient.CoachInfoById(coachId).getData();
        TApply tApply = new TApply();
        tApply.setRecruitId(recruitId);
        tApply.setApplyType(1);
        tApply.setCoachId(coachId);
        tApply.setGymNum(tRecruitCondition.getGymNum());
        tApply.setResumeId(coachInfoDto.getResumeId());
        tApply.setApplyState(0);
        tApply.setApplyDate(LocalDateTime.now());
        boolean b = save(tApply);
        if (!b) throw new AccountException(AccountExceptionCode.APPLICATION_FAILED_PLEASE_TRY_AGAIN);
        //返回给前端
        CoachJobApplicationDto dto = new CoachJobApplicationDto();
        dto.setApplyId(tApply.getApplyId());
        dto.setRecruitId(recruitId);
        dto.setJobTitle(tRecruitCondition.getJobTitle());
        dto.setGymNum(tRecruitCondition.getGymNum());
        //将json字符串转化为对象
        dto.setJobForm(JSONUtil.toBean(tRecruitCondition.getJobDetails(),JobDetailsDto.class));
        dto.setJobSalary(tRecruitCondition.getJobSalary());
        dto.setCreateName(tRecruitCondition.getCreateName());
        dto.setCreatePhone(tRecruitCondition.getCreatePhone());
        dto.setApplyType(1);
        dto.setApplyState(0);
        dto.setApplyDate(LocalDateTime.now());
        return dto;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public GymApplicationCoachDto gymRecruitApplication(Integer recruitId, Integer coachId) {

        TRecruitCondition tRecruitCondition = tRecruitConditionMapper.selectById(recruitId);
        if(tRecruitCondition==null || tRecruitCondition.getRecruitState()==0){
            throw new GymException(GymExceptionCode.RECRUIT_NOT_EXIST);
        }
        Result<CoachDto> coachDtoResult = accountServerClient.getCoachAccountById(coachId);
        CoachDto coachDto = coachDtoResult.getData();
        if (coachDto==null) throw new AccountException(AccountExceptionCode.USER_NOT_LOGIN);
        if (coachDto.getGymNum()!=null || !coachDto.getGymNum().equals("")) throw new AccountException("该教练已签约,不能发送申请",400061);

        QueryWrapper<TApply> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id", coachId).eq("recruit_id", recruitId).eq("apply_state", 0);
        TApply apply = tApplyMapper.selectOne(wrapper);
        if (apply!=null) throw new AccountException("已发送招聘申请，请勿重复操作",40071);

        CoachInfoDto coachInfoDto = accountServerClient.CoachInfoById(coachId).getData();
        TApply tApply = new TApply();
        tApply.setRecruitId(recruitId);
        tApply.setApplyType(2);
        tApply.setCoachId(coachId);
        tApply.setGymNum(tRecruitCondition.getGymNum());
        tApply.setResumeId(coachInfoDto.getResumeId());
        tApply.setApplyState(0);
        tApply.setApplyDate(LocalDateTime.now());
        boolean b = save(tApply);
        if (!b) throw new AccountException(AccountExceptionCode.APPLICATION_FAILED_PLEASE_TRY_AGAIN);
        //返回给前端
        GymApplicationCoachDto dto = new GymApplicationCoachDto();
        dto.setApplyId(tApply.getApplyId());
        dto.setRecruitId(recruitId);
        dto.setJobTitle(tRecruitCondition.getJobTitle());
        dto.setGymNum(tRecruitCondition.getGymNum());
        dto.setApplyType(2);
        dto.setCoachId(coachId);
        dto.setResumeId(coachInfoDto.getResumeId());
        dto.setCoachRealname(coachInfoDto.getCoachRealname());
        dto.setCoachPhoto(coachInfoDto.getCoachPhoto());
        dto.setCoachIdnum(coachInfoDto.getCoachIdnum());
        dto.setCoachGender(coachInfoDto.getCoachGender());
        dto.setCoachPhone(coachInfoDto.getCoachPhone());
        dto.setCoachAge(coachInfoDto.getCoachAge());
        dto.setCoachAuthen(coachInfoDto.getCoachAuthen());
        dto.setCoachDetails(coachInfoDto.getCoachDetails());
        dto.setCoachMoney(coachInfoDto.getCoachMoney());
        dto.setWantJob(coachInfoDto.getWantJob());
        dto.setCoachGood(coachInfoDto.getCoachGood());
        dto.setApplyState(0);
        dto.setApplyDate(LocalDateTime.now());
        return dto;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public TApply cancelApplication(Integer applyId, int coachId) {
        TApply tApply = tApplyMapper.selectOne(new QueryWrapper<TApply>().eq("apply_id", applyId).eq("apply_state", 0));
        if (tApply==null) throw new AccountException(AccountExceptionCode.THE_JOB_APPLICATION_WAS_NOT_FOUNT);
        if (tApply.getCoachId()!=coachId) throw new AccountException(AccountExceptionCode.YOU_DONT_HAVE_PERMISSION_TO_OPERATE);
        tApply.setApplyState(3);
        tApplyMapper.updateById(tApply);
        return tApply;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public TApply gymCancelApplication(Integer applyId) {
        TApply tApply = tApplyMapper.selectOne(new QueryWrapper<TApply>().eq("apply_id", applyId).eq("apply_state", 0));
        if (tApply==null) throw new AccountException(AccountExceptionCode.THE_JOB_APPLICATION_WAS_NOT_FOUNT);
        tApply.setApplyState(3);
        tApplyMapper.updateById(tApply);
        return tApply;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public TApply auditInformation(Integer applyId, Integer state) {
        TApply apply = tApplyMapper.selectById(applyId);
        if(apply==null){
            throw new GymException(GymExceptionCode.RECRUIT_NOT_EXIST);
        }
        apply.setApplyState(state);
        //审核通过
        if(state==1){
            CoachInfoDto coachInfo = accountServerClient.CoachInfoById(apply.getCoachId()).getData();
            TGymCoachInfo tGymCoachInfo = new TGymCoachInfo();
            tGymCoachInfo.setGymNum(apply.getGymNum());
            tGymCoachInfo.setCoachId(apply.getCoachId());
            tGymCoachInfo.setCoachType(coachInfo.getWantJob());//教练类型（求职意向）
            tGymCoachInfo.setCoachAdept(coachInfo.getCoachGood());//擅长领域
            tGymCoachInfo.setCertification(coachInfo.getCoachAuthen());//资质证书
            tGymCoachInfo.setCoachPhone(coachInfo.getCoachPhone());
            tGymCoachInfo.setJoinDate(LocalDateTime.now());
            tGymCoachInfo.setCoachState(1);
            tGymCoachInfo.setWorkState(0);//默认无课
            tGymCoachInfo.setCoachMark(0.00);
            tGymCoachInfo.setMarkNum(0);
            tGymCoachInfoMapper.insert(tGymCoachInfo);
            //教练绑定场馆
            Result<CoachDto> coachDtoResult = accountServerClient.coachBindGym(apply.getCoachId(), apply.getGymNum());
            if(coachDtoResult.getCode()!=200){
                throw new AccountException(AccountExceptionCode.NOT_FIND_THIS_USER);
            }

        }

        return apply;
    }
}
